﻿// Decompiled with JetBrains decompiler
// Type: MCM.LightInject.ImmutableHashTreeExtensions
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

#nullable disable
namespace MCM.LightInject
{
  [ExcludeFromCodeCoverage]
  internal static class ImmutableHashTreeExtensions
  {
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static TValue Search<TKey, TValue>(this ImmutableHashTree<TKey, TValue> tree, TKey key)
    {
      int hashCode = key.GetHashCode();
      while (tree.Height != 0 && tree.HashCode != hashCode)
        tree = hashCode < tree.HashCode ? tree.Left : tree.Right;
      if (!tree.IsEmpty && ((object) tree.Key == (object) key || object.Equals((object) tree.Key, (object) key)))
        return tree.Value;
      if (tree.Duplicates.Items.Length != 0)
      {
        foreach (KeyValue<TKey, TValue> keyValue in tree.Duplicates.Items)
        {
          if ((object) keyValue.Key == (object) key || object.Equals((object) keyValue.Key, (object) key))
            return keyValue.Value;
        }
      }
      return default (TValue);
    }

    public static ImmutableHashTree<TKey, TValue> Add<TKey, TValue>(
      this ImmutableHashTree<TKey, TValue> tree,
      TKey key,
      TValue value)
    {
      if (tree.IsEmpty)
        return new ImmutableHashTree<TKey, TValue>(key, value, tree, tree);
      int hashCode = key.GetHashCode();
      if (hashCode > tree.HashCode)
        return ImmutableHashTreeExtensions.AddToRightBranch<TKey, TValue>(tree, key, value);
      return hashCode < tree.HashCode ? ImmutableHashTreeExtensions.AddToLeftBranch<TKey, TValue>(tree, key, value) : new ImmutableHashTree<TKey, TValue>(key, value, tree);
    }

    public static IEnumerable<KeyValue<TKey, TValue>> InOrder<TKey, TValue>(
      this ImmutableHashTree<TKey, TValue> hashTree)
    {
      if (!hashTree.IsEmpty)
      {
        foreach (KeyValue<TKey, TValue> left in hashTree.Left.InOrder<TKey, TValue>())
          yield return new KeyValue<TKey, TValue>(left.Key, left.Value);
        yield return new KeyValue<TKey, TValue>(hashTree.Key, hashTree.Value);
        for (int i = 0; i < hashTree.Duplicates.Items.Length; ++i)
          yield return hashTree.Duplicates.Items[i];
        foreach (KeyValue<TKey, TValue> right in hashTree.Right.InOrder<TKey, TValue>())
          yield return new KeyValue<TKey, TValue>(right.Key, right.Value);
      }
    }

    private static ImmutableHashTree<TKey, TValue> AddToLeftBranch<TKey, TValue>(
      ImmutableHashTree<TKey, TValue> tree,
      TKey key,
      TValue value)
    {
      return new ImmutableHashTree<TKey, TValue>(tree.Key, tree.Value, tree.Left.Add<TKey, TValue>(key, value), tree.Right);
    }

    private static ImmutableHashTree<TKey, TValue> AddToRightBranch<TKey, TValue>(
      ImmutableHashTree<TKey, TValue> tree,
      TKey key,
      TValue value)
    {
      return new ImmutableHashTree<TKey, TValue>(tree.Key, tree.Value, tree.Left, tree.Right.Add<TKey, TValue>(key, value));
    }
  }
}
